package com.hullbreach.rogue;

import java.util.LinkedList;

import org.andengine.entity.primitive.Rectangle;
import org.andengine.extension.tmx.TMXLayer;
import org.andengine.extension.tmx.TMXProperties;
import org.andengine.extension.tmx.TMXTile;
import org.andengine.extension.tmx.TMXTileProperty;
import org.andengine.extension.tmx.TMXTiledMap;
import org.andengine.util.debug.Debug;

public class Map {
	
	/* A MAP IS THE CURRENT MAP THE PLAYER IS ON
	 * IT IS COMPRISED OF
	 * A TILE BASED VERSION - tiles
	 * A TMX VERSION - mTMXTiledMap
	 */

	//TILES
	private Tile[][] mTiles;
	private int width;
	public int width() { return width; }	
	private int height;
    public int height() { return height; }
	
    //TMX object and properties
    private TMXTiledMap mTMXTiledMap;
    private TMXLayer tmxLayer;
    private TMXTile tmxTile;
	
    //entities
	private LinkedList<GameObject> entities = new LinkedList<GameObject>();
	
	//constructor
	public Map(Tile[][] mTiles){
        this.mTiles = mTiles;
        this.width = mTiles.length;
        this.height = mTiles[0].length;
    }	
	
	//getters and setters
	public LinkedList<GameObject> getEntities() {
		return entities;
	}
	public void setEntities(LinkedList<GameObject> entities) {
		this.entities = entities;
	}
	public TMXTiledMap getTMXTiledMap() {
		return this.mTMXTiledMap;
	}
	public void setTMXTiledMap(TMXTiledMap mTMXTiledMap) {
		this.mTMXTiledMap = mTMXTiledMap;
	}
	
	
	public void generateMapTest() {
		
		Tile[][] tiles = new Tile[this.width][this.height];

		for (int x = 0; x < 200; x++) {
            for (int y = 0; y < 200; y++) {
                tiles[x][y] = Math.random() < 0.5 ? Tile.FLOOR : Tile.WALL;
            }
        }
		
        int times = 10;
        Tile[][] tiles2 = new Tile[200][200];
        for (int time = 0; time < times; time++) {
 
         for (int x = 0; x < 200; x++) {
             for (int y = 0; y < 200; y++) {
              int floors = 0;
              int rocks = 0;
 
              for (int ox = -1; ox < 2; ox++) {
                  for (int oy = -1; oy < 2; oy++) {
                   if (x + ox < 0 || x + ox >= 200 || y + oy < 0
                        || y + oy >= 200)
                       continue;
 
                   if (tiles[x + ox][y + oy] == Tile.FLOOR)
                       floors++;
                   else
                       rocks++;
                  }
              }
              tiles2[x][y] = floors >= rocks ? Tile.FLOOR : Tile.WALL;
              
             }
         }
         tiles = tiles2;
        }        
		
		int tileId;
        for (int x = 0; x < 200; x++) {
            for (int y = 0; y < 200; y++) {
                //tiles[x][y] = Math.random() < 0.5 ? Tile.FLOOR : Tile.WALL;
            	tmxTile = tmxLayer.getTMXTile(x, y);
                if(tmxTile != null){
                	tileId = tiles[x][y].globalTileId();
                	tmxTile.setGlobalTileID(this.mTMXTiledMap, tileId);
                } 
                
            }
            
        }          
		
	}
	
	
	//get the tileXY at coordinatesXY
	public int[] getTileXY( float coordX, float coordY )
	{
		int[] coordArray = {0,0};
        TMXLayer tmxLayer = getTMXTiledMap().getTMXLayers().get(0);
        tmxTile = tmxLayer.getTMXTileAt(coordX,coordY);
        
        if (tmxTile != null)
        {
        	coordArray[0]=tmxTile.getTileX();
        	coordArray[1]=tmxTile.getTileY();
    		return coordArray;
        }
        else
        {
        	return null;
        }
        
	}
	
	
	//converts a Tiles Map array to TMX format
	public void convertTilesToTMX( Tile[][] tiles )
	{
		for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                tmxTile = tmxLayer.getTMXTile(x, y);
                if(tmxTile != null){
                 		tmxTile.setGlobalTileID(this.mTMXTiledMap, tiles[x][y].globalTileId());
                }         

            }
        }    	
	}
	

	void changeTile(final float coordX, final float coordY, int globalTileId)
	{				
        TMXLayer tmxLayer = this.getTMXTiledMap().getTMXLayers().get(0);
        tmxTile = tmxLayer.getTMXTileAt(coordX,coordY);
        if(tmxTile != null){
        	tmxTile.setGlobalTileID(this.getTMXTiledMap(), globalTileId);
        }    
           
	}
	
	
	
	
	//Can delete this when maps are auto generated
    int[] findTile( final String tileName )
    {
        TMXLayer tmxLayer = this.getTMXTiledMap().getTMXLayers().get(0);
        int tmxRows = tmxLayer.getTileRows();
        int tmxCols = tmxLayer.getTileColumns();
        int[] tileCoord = {0,0};
        
        for (int y=0;y<tmxRows;y++)
        {
            for (int x=0;x<tmxCols;x++)
            {
            	tmxTile = tmxLayer.getTMXTile(x, y);
                
                if(tmxTile != null){
                	//final Integer test = tmxTile.getGlobalTileID();
                	final TMXProperties<TMXTileProperty> pTMXTileProperties;
                    pTMXTileProperties = tmxTile.getTMXTileProperties(this.getTMXTiledMap());
					if(pTMXTileProperties != null)
					{
						 if(pTMXTileProperties.containsTMXProperty("name", tileName))
						 {
							 //Debug.e("FOUND IT");
							 tileCoord[0] = x;
							 tileCoord[1] = y;
							 
							 return tileCoord;
						 }        	
					 }
                }                	
            }
        	
        }
        
        return tileCoord;
    }	
	
	
	
	
	
	//check if tile can be moved to
	public boolean canMoveTo( GameObject player, float coordX, float coordY)
	{
		boolean canMove = false;
				
        TMXLayer tmxLayer = getTMXTiledMap().getTMXLayers().get(0);
        tmxTile = tmxLayer.getTMXTileAt(coordX,coordY);
        if(tmxTile != null){
        	
        	 final TMXProperties<TMXTileProperty> pTMXTileProperties;
             pTMXTileProperties = tmxTile.getTMXTileProperties(mTMXTiledMap);
             
             if(pTMXTileProperties != null)
             { //Avoid NullPointerException
            	 if(pTMXTileProperties.containsTMXProperty("name", "wall") || pTMXTileProperties.containsTMXProperty("name", "wall2"))
            	 {
            		 //Debug.e("WALL");
            		 return false;
            	 }
            	 else
            	 { //Allow to move over non-property tiles.
                     return true;
            	 }        	
        	
             }
		
        }    

		return canMove;
	}
}
